package com.sws.wx_msg_push.service.impl;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.stream.Collectors;

import com.sws.push.domain.AIDto;
import com.sws.push.service.*;
import com.sws.push.service.AIDialogue;
import com.sws.weixin.mapper.Template2Mapper;
import com.sws.weixin.token.TokenUtil;
import com.sws.weixin.util.HttpUtil;
import com.sws.wx_msg_push.dto.ReservationReminderDTO;
import com.sws.wx_msg_push.dto.ReservationTemplateDTO;
import com.sws.wx_msg_push.service.ReservationReminderService;
import com.sws.wxtemplate.domain.WechatTemplate;
import com.sws.wx_msg_push.dto.StaffReminderDTO;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.sws.common.core.domain.AjaxResult;

import lombok.extern.slf4j.Slf4j;

/**
 * 预约提醒服务实现
 */
@Slf4j
@Service
public class ReservationReminderServiceImpl implements ReservationReminderService {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private AIDialogue aIDialogue;

    @Autowired
    @Qualifier("reservationObjectMapper")
    private ObjectMapper objectMapper;

    @Value("${wx.template.reservation-reminder-id}")
    private String reservationTemplateId;  //发送顾客微信-预约提醒记录

    @Value("${wx.template.AI-reservation-reminder-id}")
    private String reservationAITemplateId; // 发送技师微信-顾客到店（含AI话术分析）模板

    @Value("${wx.template.staff-reminder-id}")
    private String staffReservationTemplateId;  //发送技术微信-预约提醒记录

    @Value("${wx.api.base-url:https://api.weixin.qq.com}")
    private String wxApiBaseUrl;

    @Value("${wx.api.send-template-url:/cgi-bin/message/template/send}")
    private String sendTemplateUrl;

    @Autowired
    private TokenUtil tokenUtil;

    @Autowired
    private Template2Mapper template2Mapper;

    /**
     * 获取未来指定分钟内的预约
     * 
     * @param minutes 未来多少分钟内
     * @return 预约提醒列表
     */
    @Override
    public List<ReservationReminderDTO> getUpcomingStaffReservations(int minutes) {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime endTime = now.plusMinutes(minutes);

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String nowStr = now.format(formatter);
        String endTimeStr = endTime.format(formatter);

        log.info("查询预约时间范围: {} 至 {}", nowStr, endTimeStr);

        // 修改SQL查询，放宽条件，先不过滤status和openid，确保能查到数据
        String sql = "SELECT r.id as reservationId, r.customer_pid as customerPid, " +
                "r.customer_name as customerName, r.customer_phone as customerPhone, " +
                "r.service_content as serviceContent, r.staff_pid as staffPid, " +
                "r.staff_name as staffName, r.room_no as roomNo, r.appointment_time as appointmentTime, " +
                "t.openid " +
                "FROM ry_reservation r " +
                "JOIN ry_staff t ON r.staff_pid = t.pid " +
                "WHERE r.appointment_time BETWEEN ? AND ? " +
                "AND r.del_flag = 0 AND r.isSend = 0";

        try {
            // 执行查询并记录结果
            List<ReservationReminderDTO> results = jdbcTemplate.query(
                    sql,
                    new BeanPropertyRowMapper<>(ReservationReminderDTO.class),
                    nowStr, endTimeStr);

            log.info("查询到 {} 条预约记录", results.size());


            // 记录每条查询结果的基本信息，帮助调试
            for (ReservationReminderDTO dto : results) {
                log.info("预约ID: {}, 客户: {}, 时间: {}, OpenID: {}",
                        dto.getReservationId(),
                        dto.getCustomerName(),
                        dto.getAppointmentTime() != null
                                ? dto.getAppointmentTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
                                : "null",
                        dto.getOpenid() != null ? dto.getOpenid() : "未绑定");
            }

            // 过滤掉没有OpenID的记录
            List<ReservationReminderDTO> validResults = new ArrayList<>();
            for (ReservationReminderDTO dto : results) {
                if (dto.getOpenid() != null && !dto.getOpenid().isEmpty()) {
                    validResults.add(dto);
                }
            }

            log.info("过滤后有 {} 条有效预约记录(有OpenID)", validResults.size());
            return validResults;

        } catch (Exception e) {
            log.error("查询即将到来的预约失败", e);
            log.error("SQL查询语句: {}", sql);
            log.error("查询参数: now={}, endTime={}", now, endTime);
            return new ArrayList<>();
        }
    }

    /**
     * 发送客户微信-预约提醒消息
     * 
     * @param reminder 预约提醒信息
     * @return 发送结果
     */
    @Override
    public AjaxResult sendReservationReminder(ReservationReminderDTO reminder) {
        if (reminder.getOpenid() == null || reminder.getOpenid().isEmpty()) {
            return AjaxResult.error("客户未绑定微信，无法发送提醒");
        }

        try {
            // 从数据库中获取模板信息
            WechatTemplate wechatTemplate = template2Mapper.selectByWxTemplateId(reservationTemplateId);
            if (wechatTemplate == null) {
                log.error("模板ID: {} 在数据库中不存在", reservationTemplateId);
                return AjaxResult.error("模板不存在，无法发送提醒");
            }

            ReservationTemplateDTO templateMsg = new ReservationTemplateDTO();
            templateMsg.setTouser(reminder.getOpenid());
            templateMsg.setTemplateId(reservationTemplateId);

            // 获取性别称谓
            String genderTitle = reminder.getCustomerGender() != null && reminder.getCustomerGender() == 2
                    ? "女士"
                    : "先生";

            // 格式化日期时间
            String appointmentTime = reminder.getAppointmentTime().format(
                    DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));

            // 构建称呼
            String greeting = String.format("%s%s您好", reminder.getCustomerName(), genderTitle);
            if (greeting.length() > 20) {
                greeting = greeting.substring(0, 20); // 微信模板thing字段最多20个字符
            }

            // 构建服务内容
            String serviceInfo = String.format("%s", reminder.getServiceContent());
            if (serviceInfo.length() > 20) {
                serviceInfo = serviceInfo.substring(0, 20); // 微信模板thing字段最多20个字符
            }

            // 构建房间信息
            String roomInfo = reminder.getRoomNo();
            if (roomInfo != null && roomInfo.length() > 20) {
                roomInfo = roomInfo.substring(0, 20); // 微信模板thing字段最多20个字符
            }

            // 构建技师信息
            String staffInfo = reminder.getStaffName();
            if (staffInfo != null && staffInfo.length() > 20) {
                staffInfo = staffInfo.substring(0, 20); // 微信模板thing字段最多20个字符
            }

            // 构建技师电话
            String staffPhone = reminder.getStaffPhone();
            if (staffPhone != null && staffPhone.length() > 20) {
                staffPhone = staffPhone.substring(0, 20); // 微信模板thing字段最多20个字符
            }

            // 设置模板数据 - 使用数据库中定义的字段名格式
            templateMsg.addData("thing01", greeting);
            templateMsg.addData("thing02", serviceInfo);
            templateMsg.addData("time01", appointmentTime);
            templateMsg.addData("thing03", roomInfo != null ? roomInfo : "");
            templateMsg.addData("thing04", staffInfo != null ? staffInfo : "");
            templateMsg.addData("thing05", staffPhone != null ? staffPhone : "");

            // 记录将要发送的模板消息内容
            try {
                String jsonContent = objectMapper.writeValueAsString(templateMsg);
                log.info("准备发送模板消息: {}", jsonContent);
            } catch (Exception e) {
                log.warn("模板消息序列化失败", e);
            }

            // 构建完整的URL，包括access_token参数
            String fullUrl = wxApiBaseUrl + sendTemplateUrl;
            // 强制刷新获取最新的accessToken
            String accessToken = TokenUtil.getStaticAccessToken();

            if (accessToken != null && !accessToken.isEmpty()) {
                fullUrl += "?access_token=" + accessToken;
            } else {
                log.warn("微信访问令牌为空，可能导致API调用失败");
            }

            // 调用微信API发送模板消息
            log.info("直接发送模板消息到微信API: {}", fullUrl);

            // 改用HttpUtil.doPost2方法发送请求，与WxTemplateServiceImpl中的实现一致
            try {
                String jsonContent = objectMapper.writeValueAsString(templateMsg);
                String result = HttpUtil.doPost2(fullUrl, jsonContent);

                // 解析响应
                Map<String, Object> responseBody = objectMapper.readValue(result, Map.class);
                log.info("微信API响应: {}", responseBody);

                if (responseBody != null) {
                    Integer errcode = (Integer) responseBody.get("errcode");
                    if (errcode != null && errcode == 0) {
                        log.info("预约提醒发送成功, 预约ID: {}, 客户: {}", reminder.getReservationId(), reminder.getCustomerName());
                        return AjaxResult.success("预约提醒发送成功");
                    } else {
                        String errmsg = (String) responseBody.get("errmsg");
                        log.error("预约提醒发送失败, 预约ID: {}, 原因: {}", reminder.getReservationId(), errmsg);
                        return AjaxResult.error("预约提醒发送失败: " + errmsg);
                    }
                } else {
                    log.error("预约提醒发送失败, 预约ID: {}, 原因: 无响应数据", reminder.getReservationId());
                    return AjaxResult.error("预约提醒发送失败: 无响应数据");
                }
            } catch (Exception e) {
                log.error("发送预约提醒异常", e);
                return AjaxResult.error("发送预约提醒异常: " + e.getMessage());
            }

        } catch (Exception e) {
            log.error("发送预约提醒异常", e);
            return AjaxResult.error("发送预约提醒异常: " + e.getMessage());
        }
    }

    /**
     * 发送技师微信-预约提醒消息
     *
     * @param reminder 预约提醒信息
     * @return 发送结果
     */
    public AjaxResult sendStaffReservationReminder(ReservationReminderDTO reminder) {
        if (reminder.getOpenid() == null || reminder.getOpenid().isEmpty()) {
            return AjaxResult.error("技师未绑定微信，无法发送提醒");
        }

        try {
            // 从数据库中获取模板信息
            WechatTemplate wechatTemplate = template2Mapper.selectByWxTemplateId(staffReservationTemplateId);
            if (wechatTemplate == null) {
                log.error("模板ID: {} 在数据库中不存在", staffReservationTemplateId);
                return AjaxResult.error("模板不存在，无法发送提醒");
            }

            ReservationTemplateDTO templateMsg = new ReservationTemplateDTO();
            templateMsg.setTouser(reminder.getOpenid());
            templateMsg.setTemplateId(staffReservationTemplateId);

            // 格式化日期时间
            String appointmentTime = reminder.getAppointmentTime().format(
                    DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));

            // 构建称呼
            String greeting = String.format("%s%s你好", reminder.getStaffName(), "技师");
            if (greeting.length() > 20) {
                greeting = greeting.substring(0, 20); // 微信模板thing字段最多20个字符
            }

            // 构建服务内容
            String serviceInfo = String.format("%s", reminder.getServiceContent());
            if (serviceInfo.length() > 20) {
                serviceInfo = serviceInfo.substring(0, 20); // 微信模板thing字段最多20个字符
            }

            // 构建房间信息
            String roomInfo = reminder.getRoomNo();
            if (roomInfo != null && roomInfo.length() > 20) {
                roomInfo = roomInfo.substring(0, 20); // 微信模板thing字段最多20个字符
            }



            // 构建顾客信息
            String customerInfo = reminder.getCustomerName();
            if (customerInfo != null && customerInfo.length() > 20) {
                customerInfo = customerInfo.substring(0, 20); // 微信模板thing字段最多20个字符
            }



            // 设置模板数据 - 使用数据库中定义的字段名格式
            templateMsg.addData("thing01", greeting);
            templateMsg.addData("thing02", customerInfo);
            templateMsg.addData("time01", serviceInfo );
            templateMsg.addData("thing03", appointmentTime != null ? appointmentTime : "");
            templateMsg.addData("thing04", roomInfo != null ? roomInfo : "");

            // 记录将要发送的模板消息内容
            try {
                String jsonContent = objectMapper.writeValueAsString(templateMsg);
                log.info("准备发送模板消息: {}", jsonContent);
            } catch (Exception e) {
                log.warn("模板消息序列化失败", e);
            }

            // 构建完整的URL，包括access_token参数
            String fullUrl = wxApiBaseUrl + sendTemplateUrl;
            // 强制刷新获取最新的accessToken
            String accessToken = TokenUtil.getStaticAccessToken();

            if (accessToken != null && !accessToken.isEmpty()) {
                fullUrl += "?access_token=" + accessToken;
            } else {
                log.warn("微信访问令牌为空，可能导致API调用失败");
            }

            // 调用微信API发送模板消息
            log.info("直接发送模板消息到微信API: {}", fullUrl);

            // 改用HttpUtil.doPost2方法发送请求，与WxTemplateServiceImpl中的实现一致
            try {
                String jsonContent = objectMapper.writeValueAsString(templateMsg);
                String result = HttpUtil.doPost2(fullUrl, jsonContent);

                // 解析响应
                Map<String, Object> responseBody = objectMapper.readValue(result, Map.class);
                log.info("微信API响应: {}", responseBody);

                if (responseBody != null) {
                    Integer errcode = (Integer) responseBody.get("errcode");
                    if (errcode != null && errcode == 0) {
                        log.info("预约提醒发送成功, 预约ID: {}, 客户: {}", reminder.getReservationId(), reminder.getCustomerName());
                        return AjaxResult.success("预约提醒发送成功");
                    } else {
                        String errmsg = (String) responseBody.get("errmsg");
                        log.error("预约提醒发送失败, 预约ID: {}, 原因: {}", reminder.getReservationId(), errmsg);
                        return AjaxResult.error("预约提醒发送失败: " + errmsg);
                    }
                } else {
                    log.error("预约提醒发送失败, 预约ID: {}, 原因: 无响应数据", reminder.getReservationId());
                    return AjaxResult.error("预约提醒发送失败: 无响应数据");
                }
            } catch (Exception e) {
                log.error("发送预约提醒异常", e);
                return AjaxResult.error("发送预约提醒异常: " + e.getMessage());
            }

        } catch (Exception e) {
            log.error("发送预约提醒异常", e);
            return AjaxResult.error("发送预约提醒异常: " + e.getMessage());
        }
    }
    /**
     * 发送技师微信-顾客到店提醒消息（含AI话术）
     *
     * @param reminder 预约提醒信息
     * @return 发送结果
     */
    public AjaxResult sendArriveReservationReminder(ReservationReminderDTO reminder) {
        if (reminder.getOpenid() == null || reminder.getOpenid().isEmpty()) {
            return AjaxResult.error("技师未绑定微信，无法发送提醒");
        }

        try {
            // 从数据库中获取模板信息
            WechatTemplate wechatTemplate = template2Mapper.selectByWxTemplateId(reservationAITemplateId);
            if (wechatTemplate == null) {
                log.error("模板ID: {} 在数据库中不存在", reservationAITemplateId);
                return AjaxResult.error("模板不存在，无法发送提醒");
            }

            ReservationTemplateDTO templateMsg = new ReservationTemplateDTO();
            templateMsg.setTouser(reminder.getOpenid());
            templateMsg.setTemplateId(reservationAITemplateId);

            // 格式化日期时间
            String appointmentTime = reminder.getAppointmentTime().format(
                    DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));

            // 构建称呼
            String greeting = String.format("%s%s你好", reminder.getStaffName(), "技师");
            if (greeting.length() > 20) {
                greeting = greeting.substring(0, 20); // 微信模板thing字段最多20个字符
            }

            // 构建服务内容
            String serviceInfo = String.format("%s", reminder.getServiceContent());
            if (serviceInfo.length() > 20) {
                serviceInfo = serviceInfo.substring(0, 20); // 微信模板thing字段最多20个字符
            }

            // 构建房间信息
            String roomInfo = reminder.getRoomNo();
            if (roomInfo != null && roomInfo.length() > 20) {
                roomInfo = roomInfo.substring(0, 20); // 微信模板thing字段最多20个字符
            }



            // 构建顾客信息
            String customerInfo = reminder.getCustomerName();
            if (customerInfo != null && customerInfo.length() > 20) {
                customerInfo = customerInfo.substring(0, 20); // 微信模板thing字段最多20个字符
            }


            String AIAnalysis = aIDialogue.AnalyzeUsersChat(reminder.getCustomerPid()); // 限制在100个字符
            AIAnalysis = AIAnalysis != null ? AIAnalysis.replaceAll("\\n", "") : null;

            log.info("AI分析结果：" + AIAnalysis);
            if (AIAnalysis == null || AIAnalysis.length() > 100) {
                log.info("AI分析结果为空或超过200个字符");
            }
            log.info("AI分析结果：" + AIAnalysis);

            // 计算最大索引位置，防止越界
            int length = 0;
            if (AIAnalysis != null) {
                length = AIAnalysis.length();
            }
            String[] segments = new String[10];// 微信模板thing字段最多20个字符
            for (int i = 0; i < 10; i++) { // 分割为10段，每个字段最多20个字符
                int start = i * 20;
                int end = Math.min(start + 20, length);
                if (start >= length) {
                    segments[i] = "";
                } else {
                    segments[i] = AIAnalysis.substring(start, end);
                }
            }

            // 设置模板数据 - 使用数据库中定义的字段名格式
            templateMsg.addData("thing01", greeting);
            templateMsg.addData("thing02", customerInfo);
            templateMsg.addData("time01",  appointmentTime);
            templateMsg.addData("thing03", serviceInfo);
            templateMsg.addData("thing04", roomInfo != null ? roomInfo : "");
            // 设置模板数据-AI分析话术
            for (int i = 0; i < 10; i++) {
                String fieldName = String.format("thing%02d", i + 5); // 生成thing05到thing14
                String value = (i < segments.length) ? (segments[i] != null ? segments[i] : "") : "";
                templateMsg.addData(fieldName, value);
            }

            // 记录将要发送的模板消息内容
            try {
                String jsonContent = objectMapper.writeValueAsString(templateMsg);
                log.info("准备发送模板消息: {}", jsonContent);
            } catch (Exception e) {
                log.warn("模板消息序列化失败", e);
            }

            // 构建完整的URL，包括access_token参数
            String fullUrl = wxApiBaseUrl + sendTemplateUrl;
            // 强制刷新获取最新的accessToken
            String accessToken = TokenUtil.getStaticAccessToken();

            if (accessToken != null && !accessToken.isEmpty()) {
                fullUrl += "?access_token=" + accessToken;
            } else {
                log.warn("微信访问令牌为空，可能导致API调用失败");
            }

            // 调用微信API发送模板消息
            log.info("直接发送模板消息到微信API: {}", fullUrl);

            // 改用HttpUtil.doPost2方法发送请求，与WxTemplateServiceImpl中的实现一致
            try {
                String jsonContent = objectMapper.writeValueAsString(templateMsg);
                String result = HttpUtil.doPost2(fullUrl, jsonContent);

                // 解析响应
                Map<String, Object> responseBody = objectMapper.readValue(result, Map.class);
                log.info("微信API响应: {}", responseBody);

                if (responseBody != null) {
                    Integer errcode = (Integer) responseBody.get("errcode");
                    if (errcode != null && errcode == 0) {
                        log.info("预约提醒发送成功, 预约ID: {}, 客户: {}", reminder.getReservationId(), reminder.getCustomerName());
                        return AjaxResult.success("预约提醒发送成功");
                    } else {
                        String errmsg = (String) responseBody.get("errmsg");
                        log.error("预约提醒发送失败, 预约ID: {}, 原因: {}", reminder.getReservationId(), errmsg);
                        return AjaxResult.error("预约提醒发送失败: " + errmsg);
                    }
                } else {
                    log.error("预约提醒发送失败, 预约ID: {}, 原因: 无响应数据", reminder.getReservationId());
                    return AjaxResult.error("预约提醒发送失败: 无响应数据");
                }
            } catch (Exception e) {
                log.error("发送预约提醒异常", e);
                return AjaxResult.error("发送预约提醒异常: " + e.getMessage());
            }

        } catch (Exception e) {
            log.error("发送预约提醒异常", e);
            return AjaxResult.error("发送预约提醒异常: " + e.getMessage());
        }
    }

    /**
     * 执行预约提醒检查并发送
     * 
     * @param minutes 检查未来多少分钟内的预约
     * @return 结果信息
     */
    @Override
    public AjaxResult checkAndSendStaffReminders(int minutes) {
        log.info("开始检查未来{}分钟内的技师预约", minutes);

        List<ReservationReminderDTO> upcomingReservations = getUpcomingStaffReservations(minutes);

        if (upcomingReservations.isEmpty()) {
            return AjaxResult.success("未找到需要提醒的预约");
        } else {
            // 有预约信息,先主动刷新一次微信访问令牌，确保令牌有效
            try {
                String newToken = tokenUtil.forceRefreshStaticToken();
                log.info("已刷新微信访问令牌: {}", newToken);
            } catch (Exception e) {
                log.error("刷新微信访问令牌失败", e);
            }
        }

        int success = 0;
        int failed = 0;

        for (ReservationReminderDTO reminder : upcomingReservations) {
            AjaxResult result = sendStaffReservationReminder(reminder);
            if (result.isSuccess()) {
                success++;
                //设置已发送状态
                jdbcTemplate.update("UPDATE ry_reservation SET isSend = 1 WHERE id = ?",
                        reminder.getReservationId());
            } else {
                failed++;
            }
        }

        String message = String.format("预约提醒发送完成，成功: %d, 失败: %d", success, failed);
        log.info(message);

        if (failed > 0) {
            return AjaxResult.error(message);
        } else {
            return AjaxResult.success(message);
        }
    }

    /**
     * 同步微信模板到数据库
     * 
     * @return 操作结果
     */
    public AjaxResult syncTemplates() {
        try {
            // 获取访问令牌
            String accessToken = TokenUtil.getStaticAccessToken();
            if (accessToken == null || accessToken.isEmpty()) {
                return AjaxResult.error("无法获取微信访问令牌");
            }

            // 构建API URL
            String url = wxApiBaseUrl + "/cgi-bin/template/get_all_private_template?access_token=" + accessToken;

            // 发送请求获取模板列表
            String jsonResponse = HttpUtil.doGet(url);
            if (jsonResponse == null) {
                return AjaxResult.error("微信API未返回数据");
            }

            log.info("获取微信模板响应: {}", jsonResponse);

            // 解析JSON响应
            Map<String, Object> responseMap = objectMapper.readValue(jsonResponse, Map.class);
            if (responseMap.containsKey("errcode") && !Integer.valueOf(0).equals(responseMap.get("errcode"))) {
                return AjaxResult.error("获取模板列表失败: " + responseMap.get("errmsg"));
            }

            List<Map<String, Object>> templateList = (List<Map<String, Object>>) responseMap.get("template_list");
            if (templateList == null || templateList.isEmpty()) {
                return AjaxResult.success("未找到可用的模板");
            }

            log.info("找到 {} 个模板", templateList.size());

            int countNew = 0;
            int countUpdated = 0;

            for (Map<String, Object> templateData : templateList) {
                String templateId = (String) templateData.get("template_id");
                String title = (String) templateData.get("title");
                String primaryIndustry = (String) templateData.get("primary_industry");
                String deputyIndustry = (String) templateData.get("deputy_industry");
                String content = (String) templateData.get("content");
                String example = (String) templateData.get("example");

                log.info("处理模板: ID={}, 标题={}", templateId, title);

                // 将模板存储到数据库
                try {
                    // 生成标准JSON格式的模板内容
                    String formattedContent = generateTemplateContent(content);

                    // 检查模板是否存在
                    WechatTemplate existingTemplate = template2Mapper.selectByWxTemplateId(templateId);

                    if (existingTemplate == null) {
                        log.info("添加新模板: {}", title);

                        // 创建新的com.sws.weixin.entity.TemplateInfo对象
                        com.sws.weixin.entity.TemplateInfo templateInfo = new com.sws.weixin.entity.TemplateInfo();
                        templateInfo.setTemplateId(templateId);
                        templateInfo.setTitle(title);
                        templateInfo.setPrimaryIndustry(primaryIndustry);
                        templateInfo.setDeputyIndustry(deputyIndustry);
                        templateInfo.setContent(content);
                        templateInfo.setExample(example);

                        // 保存模板
                        template2Mapper.insertOrUpdate(templateInfo);
                        countNew++;
                    } else {
                        log.info("更新模板: {}", title);

                        // 创建com.sws.weixin.entity.TemplateInfo对象进行更新
                        com.sws.weixin.entity.TemplateInfo templateInfo = new com.sws.weixin.entity.TemplateInfo();
                        templateInfo.setTemplateId(templateId);
                        templateInfo.setTitle(title);
                        templateInfo.setPrimaryIndustry(primaryIndustry);
                        templateInfo.setDeputyIndustry(deputyIndustry);
                        templateInfo.setContent(content);
                        templateInfo.setExample(example);

                        // 更新模板
                        template2Mapper.insertOrUpdate(templateInfo);
                        countUpdated++;
                    }
                } catch (Exception e) {
                    log.error("保存模板失败: {}", templateId, e);
                }
            }

            String resultMsg = String.format("同步模板完成，新增: %d，更新: %d", countNew, countUpdated);
            log.info(resultMsg);
            return AjaxResult.success(resultMsg);
        } catch (Exception e) {
            log.error("同步模板异常", e);
            return AjaxResult.error("同步模板异常: " + e.getMessage());
        }
    }

    /**
     * 生成标准JSON格式的模板内容
     * 
     * @param content 原始内容
     * @return JSON格式化后的内容
     */
    private String generateTemplateContent(String content) {
        try {
            // 解析模板内容，提取字段
            Map<String, Object> templateData = new HashMap<>();
            Map<String, Object> dataFields = new HashMap<>();

            String[] lines = content.split("\n");
            for (String line : lines) {
                if (line.contains(".DATA")) {
                    // 提取字段名
                    int start = line.indexOf("{{") + 2;
                    int end = line.indexOf(".DATA");
                    if (start >= 2 && end > start) {
                        String fieldName = line.substring(start, end);

                        // 创建字段值对象
                        Map<String, Object> fieldData = new HashMap<>();
                        fieldData.put("value", "默认值");
                        fieldData.put("color", "#173177");

                        dataFields.put(fieldName, fieldData);
                    }
                }
            }

            templateData.put("data", dataFields);
            return objectMapper.writeValueAsString(templateData);
        } catch (Exception e) {
            log.error("生成模板内容JSON失败", e);
            return "{}";
        }
    }

    /**
     * 获取模板详情
     * 
     * @param templateId 模板ID
     * @return 模板详情
     */
    public AjaxResult getTemplateDetail(String templateId) {
        try {
            if (templateId == null || templateId.isEmpty()) {
                return AjaxResult.error("模板ID不能为空");
            }

            // 从数据库获取模板信息
            WechatTemplate template = template2Mapper.selectByWxTemplateId(templateId);
            if (template == null) {
                return AjaxResult.error("模板不存在");
            }

            // 构建模板详情
            Map<String, Object> detail = new HashMap<>();
            detail.put("templateId", template.getTemplateId());
            detail.put("name", template.getName());
            detail.put("content", template.getContent());
            detail.put("status", template.getStatus());

            // 解析模板字段
            Map<String, String> fields = parseTemplateFields(template.getContent());
            detail.put("fields", fields);

            return AjaxResult.success(detail);
        } catch (Exception e) {
            log.error("获取模板详情异常", e);
            return AjaxResult.error("获取模板详情异常: " + e.getMessage());
        }
    }

    /**
     * 解析模板字段
     * 
     * @param content 模板内容
     * @return 字段映射
     */
    private Map<String, String> parseTemplateFields(String content) {
        Map<String, String> fields = new HashMap<>();
        try {
            // 尝试解析JSON格式
            Map<String, Object> contentMap = objectMapper.readValue(content, Map.class);
            Map<String, Object> data = (Map<String, Object>) contentMap.get("data");
            if (data != null) {
                for (String key : data.keySet()) {
                    fields.put(key, key);
                }
                return fields;
            }
        } catch (Exception e) {
            // 非JSON格式，尝试解析文本格式
            log.debug("不是JSON格式的模板内容，尝试解析文本");
        }

        try {
            // 解析微信模板格式的字段
            String[] lines = content.split("\n");
            for (String line : lines) {
                if (line.contains(".DATA")) {
                    int start = line.indexOf("{{") + 2;
                    int end = line.indexOf(".DATA");
                    if (start >= 2 && end > start) {
                        String fieldName = line.substring(start, end);
                        fields.put(fieldName, fieldName);
                    }
                }
            }
        } catch (Exception e) {
            log.error("解析模板字段异常", e);
        }

        return fields;
    }

    /**
     * 
     * @param minutes 未来多少分钟内
     * @return 顾客预约提醒列表
     */
    @Override
    public List<ReservationReminderDTO> getUpcomingReservations(int minutes) {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime endTime = now.plusMinutes(minutes);

        log.info("查询技师预约时间范围: {} 至 {}",
                now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")),
                endTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

        // SQL查询，加入技师信息,openid字段传入顾客微信openid
        String sql = "SELECT r.id as reservationId, r.staff_pid as staffPid, " +
                "r.staff_name as staffName, s.phone as staffPhone, s.gender as staffGender, " +
                "c.openid as openid, r.customer_pid as customerPid, r.customer_name as customerName, " +
                "s.phone as staffPhone, c.gender as customerGender, " +
                "r.service_content as serviceContent, r.room_no as roomNo, r.appointment_time as appointmentTime " +
                "FROM ry_reservation r " +
                "JOIN ry_staff s ON r.staff_pid = s.pid " +
                "JOIN ry_customer c ON r.customer_pid = c.pid " +
                "WHERE r.appointment_time BETWEEN ? AND ? " +
                "AND r.del_flag = 0 AND r.isCustomerSend = 0";

        try {
            // 执行查询并记录结果
            List<ReservationReminderDTO> results = jdbcTemplate.query(
                    sql,
                    new BeanPropertyRowMapper<>(ReservationReminderDTO.class),
                    now, endTime);

            log.info("查询到 {} 条顾客预约记录", results.size());

            // 记录每条查询结果的基本信息，帮助调试
            for (ReservationReminderDTO dto : results) {
                log.info("预约ID: {}, 技师: {}, 客户: {}, 时间: {}, 顾客OpenID: {}",
                        dto.getReservationId(),
                        dto.getStaffName(),
                        dto.getCustomerName(),
                        dto.getAppointmentTime() != null
                                ? dto.getAppointmentTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
                                : "null",
                        dto.getOpenid() != null ? dto.getOpenid() : "未绑定");
            }

            // 过滤掉没有OpenID的记录
            List<ReservationReminderDTO> validResults = new ArrayList<>();
            for (ReservationReminderDTO dto : results) {
                if (dto.getOpenid() != null && !dto.getOpenid().isEmpty()) {
                    validResults.add(dto);
                }
            }

            log.info("过滤后有 {} 条有效顾客预约记录(有OpenID)", validResults.size());
            return validResults;

        } catch (Exception e) {
            log.error("查询即将到来的顾客预约失败", e);
            log.error("SQL查询语句: {}", sql);
            log.error("查询参数: now={}, endTime={}", now, endTime);
            return new ArrayList<>();
        }
    }

    /**
     * 发送技师预约提醒消息
     * 
     * @param reminder 技师预约提醒信息
     * @return 发送结果
     */
//    @Override
//    public AjaxResult sendStaffReservationReminder(StaffReminderDTO reminder) {
//        if (reminder.getOpenid() == null || reminder.getOpenid().isEmpty()) {
//            return AjaxResult.error("技师未绑定微信，无法发送提醒");
//        }
//
//        try {
//            // 从数据库中获取模板信息
//            WechatTemplate wechatTemplate = template2Mapper.selectByWxTemplateId(staffReservationTemplateId);
//            if (wechatTemplate == null) {
//                log.error("模板ID: {} 在数据库中不存在", staffReservationTemplateId);
//                return AjaxResult.error("模板不存在，无法发送提醒");
//            }
//
//            ReservationTemplateDTO templateMsg = new ReservationTemplateDTO();
//            templateMsg.setTouser(reminder.getOpenid());
//            templateMsg.setTemplateId(staffReservationTemplateId);
//
//            // 获取技师性别称谓
//            String staffGenderTitle = reminder.getStaffGender() != null && reminder.getStaffGender() == 2
//                    ? "女士"
//                    : "先生";
//
//            // 获取客户性别称谓
//            String customerGenderTitle = reminder.getCustomerGender() != null && reminder.getCustomerGender() == 2
//                    ? "女士"
//                    : "先生";
//
//            // 格式化日期时间
//            String appointmentTime = reminder.getAppointmentTime().format(
//                    DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
//
//            // 构建技师称呼
//            String staffGreeting = String.format("%s%s您好", reminder.getStaffName(), staffGenderTitle);
//            if (staffGreeting.length() > 20) {
//                staffGreeting = staffGreeting.substring(0, 20); // 微信模板thing字段最多20个字符
//            }
//
//            // 构建客户称呼
//            String customerGreeting = String.format("%s%s", reminder.getCustomerName(), customerGenderTitle);
//            if (customerGreeting.length() > 20) {
//                customerGreeting = customerGreeting.substring(0, 20); // 微信模板thing字段最多20个字符
//            }
//
//            // 构建服务内容
//            String serviceInfo = reminder.getServiceContent();
//            if (serviceInfo != null && serviceInfo.length() > 20) {
//                serviceInfo = serviceInfo.substring(0, 20); // 微信模板thing字段最多20个字符
//            }
//
//            // 构建房间信息
//            String roomInfo = reminder.getRoomNo();
//            if (roomInfo != null && roomInfo.length() > 20) {
//                roomInfo = roomInfo.substring(0, 20); // 微信模板thing字段最多20个字符
//            }
//
//            // 设置模板数据 - 使用数据库中定义的字段名格式
//            templateMsg.addData("thing01", staffGreeting);
//            templateMsg.addData("thing02", customerGreeting);
//            templateMsg.addData("thing03", serviceInfo != null ? serviceInfo : "");
//            templateMsg.addData("time01", appointmentTime);
//            templateMsg.addData("thing04", roomInfo != null ? roomInfo : "");
//
//            // 记录将要发送的模板消息内容
//            try {
//                String jsonContent = objectMapper.writeValueAsString(templateMsg);
//                log.info("准备发送技师预约模板消息: {}", jsonContent);
//            } catch (Exception e) {
//                log.warn("技师预约模板消息序列化失败", e);
//            }
//
//            // 构建完整的URL，包括access_token参数
//            String fullUrl = wxApiBaseUrl + sendTemplateUrl;
//            // 强制刷新获取最新的accessToken
//            String accessToken = TokenUtil.getStaticAccessToken();
//
//            if (accessToken != null && !accessToken.isEmpty()) {
//                fullUrl += "?access_token=" + accessToken;
//            } else {
//                log.warn("微信访问令牌为空，可能导致API调用失败");
//            }
//
//            // 调用微信API发送模板消息
//            log.info("直接发送技师预约模板消息到微信API: {}", fullUrl);
//
//            // 使用HttpUtil.doPost2方法发送请求
//            try {
//                String jsonContent = objectMapper.writeValueAsString(templateMsg);
//                String result = HttpUtil.doPost2(fullUrl, jsonContent);
//
//                // 解析响应
//                Map<String, Object> responseBody = objectMapper.readValue(result, Map.class);
//                log.info("技师预约模板消息微信API响应: {}", responseBody);
//
//                if (responseBody != null) {
//                    Integer errcode = (Integer) responseBody.get("errcode");
//                    if (errcode != null && errcode == 0) {
//                        log.info("技师预约提醒发送成功, 预约ID: {}, 技师: {}, 客户: {}",
//                                reminder.getReservationId(), reminder.getStaffName(), reminder.getCustomerName());
//                        return AjaxResult.success("技师预约提醒发送成功");
//                    } else {
//                        String errmsg = (String) responseBody.get("errmsg");
//                        log.error("技师预约提醒发送失败, 预约ID: {}, 原因: {}", reminder.getReservationId(), errmsg);
//                        return AjaxResult.error("技师预约提醒发送失败: " + errmsg);
//                    }
//                } else {
//                    log.error("技师预约提醒发送失败, 预约ID: {}, 原因: 无响应数据", reminder.getReservationId());
//                    return AjaxResult.error("技师预约提醒发送失败: 无响应数据");
//                }
//            } catch (Exception e) {
//                log.error("发送技师预约提醒异常", e);
//                return AjaxResult.error("发送技师预约提醒异常: " + e.getMessage());
//            }
//
//        } catch (Exception e) {
//            log.error("发送技师预约提醒异常", e);
//            return AjaxResult.error("发送技师预约提醒异常: " + e.getMessage());
//        }
//    }

    /**
     * 执行技师预约提醒检查并发送
     * 
     * @param minutes 检查未来多少分钟内的预约
     * @return 结果信息
     */
    @Override
    public AjaxResult checkAndSendReminders(int minutes) {
        log.info("开始检查未来{}分钟内的顾客预约", minutes);

        List<ReservationReminderDTO> upcomingReservations = getUpcomingReservations(minutes);

        if (upcomingReservations.isEmpty()) {
            return AjaxResult.success("未找到需要提醒的顾客预约");
        } else {
            // 有预约信息，准备发送，先主动刷新一次微信访问令牌，确保令牌有效
            try {
                String newToken = TokenUtil.forceRefreshStaticToken();
                log.info("已刷新微信访问令牌: {}", newToken);
            } catch (Exception e) {
                log.error("刷新微信访问令牌失败", e);
            }
        }

        int success = 0;
        int failed = 0;

        for (ReservationReminderDTO reminder : upcomingReservations) {
            AjaxResult result = sendReservationReminder(reminder);
            if (result.isSuccess()) {
                success++;
                //设置已发送状态
                jdbcTemplate.update("UPDATE ry_reservation SET isCustomerSend = 1 WHERE id = ?",
                        reminder.getReservationId());
            } else {
                failed++;
            }
        }

        String message = String.format("顾客预约提醒发送完成，成功: %d, 失败: %d", success, failed);
        log.info(message);

        if (failed > 0) {
            return AjaxResult.error(message);
        } else {
            return AjaxResult.success(message);
        }
    }
}



